
#include <stdbool.h>
#include <gio/gio.h>
#include <libxml/encoding.h>
#include <libxml/xmlwriter.h>
#include "sqlite3.h"

static void node_add(void *node, const gchar *name, const gchar *value)
{
  xmlAttrPtr attr;

  if (value) {
    if (strlen(value) > 0) {
      attr = xmlHasProp(node, BAD_CAST name);
      if (!attr)
        xmlNewProp(node, BAD_CAST name, BAD_CAST value);
    }
  }
}
static int sql_callback(void *ptr, int n_column, char **column_value,
    char **column_name)
{
  int rc = 0, i = 0;
  xmlNodePtr root_node = NULL, node = NULL;

  if (n_column == 0) {
    g_debug("sql: column is 0\n");
    return true;
  }
  if (ptr) {
    root_node = ptr;
    node = xmlNewChild(root_node, NULL, BAD_CAST "Item", NULL);
    for(i = 0; i < n_column; i++) {
      node_add(node, column_name[i], column_value[i]);
    }
  }
  return rc;
}
void *gz_device_model(const char *db_name, const char *table, const char *filename)
{
  gint rc = 0;
  sqlite3 *sql = NULL;
  gchar *errmsg = NULL, statement[1024] = {0};
  xmlDocPtr doc;
  xmlNodePtr node = NULL;

  doc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
  node = xmlNewDocNode(doc, NULL, BAD_CAST "Device_Model", NULL);
  xmlDocSetRootElement(doc, node);

	g_debug("L%d f-%s [%s]%s:\n", __LINE__, __func__, db_name, table);// & 0x00ff);
  rc = sqlite3_open(db_name, &sql);
  if (rc != SQLITE_OK) {
    g_warning("%s", sqlite3_errmsg(sql));
    return NULL;
  }
  snprintf(statement, sizeof(statement),
      "select substation_code as station_code,substation_name as station_name,* from %s;",
      table);
  rc = sqlite3_exec(sql, statement, sql_callback, node, &errmsg);
  if (rc != SQLITE_OK) {
    g_warning("SELECT:%s:%s:%d\n", statement, errmsg, rc);
  }
  xmlSaveFileEnc(filename, doc, "UTF-8");
  xmlFreeDoc(doc);
  sqlite3_close(sql);
  return NULL;
}
void *gz_init(const char *src, const char *dst, const char *type, const char *no,
    void **inner_p)
{
  xmlDocPtr doc;
  xmlNodePtr node = NULL, node1;
  GDateTime *dt = NULL, *ndt = NULL;
  char *time_str = NULL;

  doc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
  node = xmlNewDocNode(doc, NULL, BAD_CAST "PatrolDevice", NULL);
  xmlDocSetRootElement(doc, node);

  xmlNewChild(node, NULL, BAD_CAST "SendCode", BAD_CAST src);
  xmlNewChild(node, NULL, BAD_CAST "ReceiveCode", BAD_CAST dst);
  xmlNewChild(node, NULL, BAD_CAST "Type", BAD_CAST type);
  xmlNewChild(node, NULL, BAD_CAST "Code", BAD_CAST no);
  xmlNewChild(node, NULL, BAD_CAST "Command", NULL);
  dt = g_date_time_new_now_utc();
  ndt = g_date_time_add_hours(dt, 8);
  time_str = g_date_time_format(ndt, "%Y-%m-%d %H:%M:%S");
  g_date_time_unref(dt);
  g_date_time_unref(ndt);
  xmlNewChild(node, NULL, BAD_CAST "Time", BAD_CAST time_str);
  node1 = xmlNewChild(node, NULL, BAD_CAST "Items", NULL);
  free(time_str);
  *inner_p = node1;

  return doc;
}
void *gz_node_add_path(void *node, const char *value)
{
  xmlNodePtr child = NULL;

  child = xmlNewChild(node, NULL, BAD_CAST "Item", NULL);
  xmlNewProp(child, BAD_CAST "device_file_path", BAD_CAST value);

  return NULL;
}
void *gz_node_add_value(void *node, const char *pid, const char *type,
    const char *tname, const char *value)
{
  xmlNodePtr child = NULL;
  GDateTime *dt = NULL, *ndt = NULL;
  char *time_str = NULL;

  child = xmlNewChild(node, NULL, BAD_CAST "Item", NULL);
  xmlNewProp(child, BAD_CAST "point_code", BAD_CAST pid);
  xmlNewProp(child, BAD_CAST "task_name", BAD_CAST tname);
  xmlNewProp(child, BAD_CAST "file_type", BAD_CAST type);
  xmlNewProp(child, BAD_CAST "device_file_path", BAD_CAST value);
  dt = g_date_time_new_now_utc();
  ndt = g_date_time_add_hours(dt, 8);
  time_str = g_date_time_format(ndt, "%Y-%m-%d %H:%M:%S");
  g_date_time_unref(dt);
  g_date_time_unref(ndt);
  xmlNewChild(child, NULL, BAD_CAST "time", BAD_CAST time_str);
  free(time_str);

  return NULL;
}
void *gz_dump(void *doc)
{
  xmlChar *doc_txt = NULL;
  char *res = NULL;
  int len;

  xmlDocDumpMemoryEnc(doc, &doc_txt, &len, "UTF-8");
  xmlFreeDoc(doc);
  res = g_strdup((char *)doc_txt);
  xmlFree(doc_txt);

  return res;
}
